from contextlib import asynccontextmanager

import uvicorn
from fastapi import FastAPI
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.gzip import GZipMiddleware

from fastapi.staticfiles import StaticFiles

from routers import (senior_01_operator_router,
                     senior_02_extra_status_code,
                     senior_03_direct_response,
                     senior_04_custom_response,
                     senior_05_other_response,senior_06_cookie,senior_07_header,
                     senior_08_depends,senior_09_security,senior_10_direct_request,
                     senior_11_dataclass,senior_12_middleware,senior_13_templates,
                     senior_14_websockets,senior_15_redis,senior_16_sqlmodel,senior_17_timed_task
)



def answer_to_everything_ml_model(x: float):
    return x * 42

ml_models = {}

# 创建一个异步函数lifespan
@asynccontextmanager
async def lifespan(app: FastAPI):
    # 加载模型
    ml_models["answer_to_everything"] = answer_to_everything_ml_model
    print("加载模型成功")
    yield
    # 清理模型
    ml_models.clear()
    print("清理模型成功")



# 创建FastAPI实例，禁用掉FastAPI会自动生成Swagger UI和Redoc文档
app = FastAPI(docs_url=None, redoc_url=None,lifespan=lifespan)

# 静态文件挂载（路由与静态文件映射）
app.mount("/static", StaticFiles(directory="../statics"), name="static")


# 重新提供一个Swagger UI，相当于我们自己重写了这么一个路由
@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )

# 这里与Swagger UI一样，重新提供Redoc
@app.get("/redoc", include_in_schema=False)
def custom_redoc():
    return get_redoc_html(
        openapi_url = "/openapi.json",
        title = "Redoc for FastAPI",
        redoc_js_url="/static/redoc.standalone.js"
    )

app.include_router(senior_01_operator_router.router,prefix="/operation",tags=["路径操作高级配置"])
app.include_router(senior_02_extra_status_code.router,prefix="/statusCode",tags=["额外状态码"])
app.include_router(senior_03_direct_response.router,prefix="/response",tags=["直接返回响应"])
app.include_router(senior_04_custom_response.router,prefix="/custom_response",tags=["自定义响应"])
app.include_router(senior_05_other_response.router,prefix="/other_response",tags=["其它响应"])
app.include_router(senior_06_cookie.router,prefix="/cookie",tags=["响应Cookies"])
app.include_router(senior_07_header.router,prefix="/header",tags=["响应头"])
app.include_router(senior_08_depends.router,prefix="/depends",tags=["高级依赖项"])
app.include_router(senior_09_security.router,prefix="/security",tags=["安全"])
app.include_router(senior_10_direct_request.router,prefix="/request",tags=["直接使用request"])
app.include_router(senior_11_dataclass.router,prefix="/dataclass",tags=["使用数据类"])
app.include_router(senior_12_middleware.router,prefix="/middleware",tags=["中间件"])
app.include_router(senior_13_templates.router,prefix="/template",tags=["模板"])
app.include_router(senior_14_websockets.router,prefix="/ws",tags=["websockets"])
app.include_router(senior_15_redis.router,prefix="/redis",tags=["Redis"])
app.include_router(senior_16_sqlmodel.router,prefix="/sql",tags=["SQLModel"])
app.include_router(senior_17_timed_task.router,prefix="/jobs",tags=["定时任务"])


# 这里注册中间件，调用的是senior_12_middleware中的register_middleware方法,把当前的app对象传过去
# senior_12_middleware.register_middleware(app,[{HTTPSRedirectMiddleware:{}}])
# senior_12_middleware.register_middleware(app,[])
senior_12_middleware.register_middleware(app,
                                         [
                                             {
                                                 TrustedHostMiddleware:{
                                                     "allowed_hosts":["example.com","*.example.com","127.0.0.1","localhost"]
                                                 }
                                             },
                                             {
                                                 GZipMiddleware:{
                                                     "minimum_size":1000,
                                                     "compresslevel":5
                                                 }
                                             }
                                         ])




@app.get("/predict")
async def predict(x: float):
    result = ml_models["answer_to_everything"](x)
    return {"result": result}

@app.get("/app")
def read_main():
    return {"message": "Hello World from main app"}


subapi = FastAPI()


@subapi.get("/sub")
def read_sub():
    return {"message": "Hello World from sub API"}


app.mount("/subapi", subapi)

if __name__ == '__main__':
    app.debug = True
    uvicorn.run("main:app", host="127.0.0.1", port=8032, reload=True)

